package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.pojo.goods.Category;
import com.qingcheng.pojo.goods.Sku;
import com.qingcheng.pojo.order.OrderItem;
import com.qingcheng.service.goods.CategoryService;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.order.CartService;
import com.qingcheng.service.order.PreferentialService;
import com.qingcheng.util.CacheKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import javax.swing.text.Keymap;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 购物车  服务
 *
 * @author 岳剑飞
 * @Company http://www.ithiema.com
 */
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Reference
    private CategoryService categoryService;

    @Reference
    private SkuService skuService;

    /**
     * 从redis中提取购物车 列表
     *
     * @param username 用户
     * @return
     */
    @Override
    public List<Map<String, Object>> findCartList(String username) {
        System.out.println("从redis中提取购物车:" + username);
        //1. 从redis缓存中获取 购物车列表信息
        List<Map<String, Object>> cartList = (List<Map<String, Object>>) redisTemplate.boundHashOps(CacheKey.CART_LIST).get(username);

        if (cartList == null) {
            //如果该用户的购物车不存在
            return new ArrayList<>();   //返回一个空的购物车列表
        }
        return cartList;
    }

    /**
     * 添加商品到购物车
     *
     * @param username
     * @param skuId
     * @param num
     */
    @Override
    public void addItem(String username, String skuId, Integer num) {
        //实现思路: 遍历购物车,如果购物车中存在该商品则累加数量,如果不存在则添加购物车项
        //1. 获取购物车
        List<Map<String, Object>> cartList = findCartList(username);

        //2. 判断是否在购物车中存在
        boolean flag = false; //是否在购物车中存在
        //遍历购物车列表
        for (Map<String, Object> map : cartList) {
            //2.1 获取购物车 详情
            OrderItem orderItem = (OrderItem) map.get("item");
            if (orderItem.getSkuId().equals(skuId)) {// 购物车存在该商品
                // 添加或者删除前判断该商品数量是否合法
                if (orderItem.getNum() <= 0) { //如果商品数量小于0
                    cartList.remove(map);   //购物车项删除
                    break;
                }
                int weight = orderItem.getWeight() / orderItem.getNum();  //计算单个商品重量

                orderItem.setNum(orderItem.getNum() + num); //数量累加
                orderItem.setMoney(orderItem.getNum() * orderItem.getPrice());  //总金额计算
                orderItem.setWeight(weight * orderItem.getNum()); //计算总重量

                // 添加或者删除后判断该商品数量是否合法
                if (orderItem.getNum() <= 0) { //如果商品数量小于0
                    cartList.remove(map);   //购物车项删除

                }
                flag = true;
                break;
            }

        }

        //2.2 如果购物车中没有该商品,则添加
        if (flag == false) {
            //1. 根据skuId 获取该商品的详细信息
            Sku sku = skuService.findById(skuId);

            if (sku == null) {
                throw new RuntimeException("该商品不存在");
            }
            if (!"1".equals(sku.getStatus())) {
                throw new RuntimeException("商品状态不合法");
            }
            if (num < 0) {
                throw new RuntimeException("商品数量不合法");
            }

            // 2. 新建一个 购物车 对象,用来封装 提交的购物车信息
            OrderItem orderItem = new OrderItem();

            orderItem.setSkuId(skuId);
            orderItem.setSpuId(sku.getSpuId());
            orderItem.setNum(num);          //商品数量计算
            orderItem.setImage(sku.getImage()); //商品图片
            orderItem.setPrice(sku.getPrice()); //商品的单价
            orderItem.setName(sku.getName());   //商品名称
            orderItem.setMoney(orderItem.getPrice() * num);//金额计算

            if (sku.getWeight() == null) { //商品的单重是否为 null
                sku.setWeight(0);
            }
            orderItem.setWeight(sku.getWeight() * num);   //重要计算

            //商品分类
            orderItem.setCategoryId3(sku.getCategoryId());   //封装商品的3 级分类
            //从缓存中 获取商品的三级分类
            Category category3 = (Category) redisTemplate.boundHashOps(CacheKey.CATEGORY).get(sku.getCategoryId());

            if (category3 == null) {
                //若缓存中为null,,  从数据库中 查询3级分类  存入缓存
                category3 = categoryService.findById(sku.getCategoryId());
                redisTemplate.boundHashOps(CacheKey.CATEGORY).put(sku.getCategoryId(), category3);
            }

            orderItem.setCategoryId2(category3.getParentId());   //封装商品的2 级分类
            //从缓存中 获取商品的2级分类
            Category category2 = (Category) redisTemplate.boundHashOps(CacheKey.CATEGORY).get(category3.getParentId());

            if (category2 == null) {
                //若缓存中为null,,  从数据库中 查询2级分类  存入缓存
                category2 = categoryService.findById(category3.getParentId());
                redisTemplate.boundHashOps(CacheKey.CATEGORY).put(sku.getCategoryId(), category3);
            }

            orderItem.setCategoryId1(category2.getParentId());   //封装商品的1 级分类


            Map map = new HashMap();
            map.put("item", orderItem);
            map.put("checked", true);  //默认选中
            cartList.add(map);

        }

        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username, cartList);

    }

    /**
     * 更新 选中状态
     *
     * @param username
     * @param skuId
     * @param checked
     * @return
     */
    @Override
    public boolean updateChecked(String username, String skuId, boolean checked) {

        //获取购物车
        List<Map<String, Object>> cartList = findCartList(username);
        //判断缓存中是否含有已购物商品
        boolean isOk = false;
        //遍历购物车列表
        for (Map map : cartList) {
            //获取购物车详细
            OrderItem orderItem = (OrderItem) map.get("item");

            if (orderItem.getSkuId().equals(skuId)) {
                map.put("checked", checked); //选中状态
                isOk = true;  //修改状态执行成功
                break;
            }
        }

        if (isOk) { //修改状态修改成功

            redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username, cartList);//存入缓存
        }
        return isOk;
    }

    /**
     * 删除选中的购物车
     *
     * @param username
     */
    @Override
    public void deleteCheckedCart(String username) {
        //获取未选中的购物车
        List<Map<String, Object>> carList = findCartList(username).stream().filter(cart -> (boolean) cart.get("checked") == false).
                collect(Collectors.toList());

        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username, carList);  //存入缓存
    }

    @Autowired
    private PreferentialService preferentialService;

    /**
     * 计算当前选中的购物车的优惠金额
     *
     * @param username
     * @return
     */
    @Override
    public int preferential(String username) {
        // 使用steam 流 获取选中的购物车
        List<OrderItem> orderItemList = findCartList(username).stream().filter(cart -> (boolean) cart.get("checked") == true)
                .map(cart -> (OrderItem) cart.get("item")).collect(Collectors.toList());

        //按分类聚合统计每个分类的金额  group by
        Map<Integer, IntSummaryStatistics> cartMap = orderItemList.stream().collect(Collectors.groupingBy(OrderItem::getCategoryId3,
                Collectors.summarizingInt(OrderItem::getMoney)));

        //循环结果 统计每个分类的优惠金额  并累加
        int allPreMoney = 0;  //累计优惠金额
        for (Integer categoryId : cartMap.keySet()) {
            //获取商品类的消费金额
            int money = (int) cartMap.get(categoryId).getSum();
            int preMoney = preferentialService.findPreMoneyByCategoryId(categoryId, money); //获取优惠金额

            System.out.println("分类: " + categoryId + " 消费金额: " + money + " 优惠金额: " + preMoney);

            allPreMoney += preMoney;
        }

        return allPreMoney;
    }

    /**
     * 获取最新的购物车列表
     *
     * @param username
     * @return
     */
    @Override
    public List<Map<String, Object>> findNewOrderItemList(String username) {
        // 获取选中的购物车
        List<Map<String, Object>> cartList = findCartList(username);

        //循环遍历购物车列表, 从数据库中重新读取每个商品的最新价格
        for (Map<String, Object> cart : cartList) {
            OrderItem orderItem = (OrderItem) cart.get("item"); //获取购物车商品明细
            Sku sku = skuService.findById(orderItem.getSkuId()); //根据商品的skuId获取商品对象
            orderItem.setPrice(sku.getPrice());  //更新购物车中的商品价格
            orderItem.setMoney(sku.getPrice() * orderItem.getNum());  //更新金额
        }
        //重新存入缓存
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(username, cartList);
        return cartList;
    }


}
